/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2002-2007, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */
package scala.reflect


/** A Manifest[T] is a descriptor for the type T. 
 *  The object `Manifest' defines factory methods for manifests which still need to be implemented.
 *  Also still to be done are manifests for refinement types.
 */
object Manifest {

  /** Manifest for the singleton type `value.type'
   */
  def singleType[T](value: Any): Manifest[T] = null

  /** Manifest for the class type `clazz', where `clazz' is
   *  a top-level or static class 
   */
  def classType[T](clazz: Predef.Class[_]): Manifest[T] = {
    val eagername = clazz.getName()
    val maybecaseProductView: T=>Option[Product] = { (t:T) =>
      if (clazz.getInterfaces.contains(classOf[Product])) Some(t.asInstanceOf[Product]) else None
    }
    
    new classManifest[T]() { val reflectedClass = clazz; val name=eagername ; val caseProductView = maybecaseProductView;}
  }

  /** Manifest for the class type `clazz[args]', where `clazz' is
   *  a top-level or static class 
   */
  def classType[T](clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = throw new Exception("clazz[args] not yet impl")

  /** Manifest for the class type `prefix # clazz'
   */
  def classType[T](prefix: Manifest[_], clazz: Predef.Class[_]): Manifest[T] =  {
    val eagername = clazz.getName()
    val ctorlist  = clazz.getDeclaredConstructors().toList
    val maybecaseProductView: T=>Option[Product] = { (t:T) =>
      if (clazz.getInterfaces.contains(classOf[Product])) Some(t.asInstanceOf[Product]) else None
    }
    
    new classManifest[T]() { val reflectedClass = clazz; val name=eagername ; val caseProductView = maybecaseProductView;}
 }

  /** Manifest for the class type `prefix # clazz[args]'
   */
  def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = throw new Exception("cprefix # clazz[args] not yet impl")

  /** Manifest for the abstract type `prefix # name'
   */
  def abstractType[T](prefix: Manifest[_], name: String): Manifest[T] = null

  /** Manifest for the abstract type `prefix # name[args]'
   */
  def abstractType[T](prefix: Manifest[_], name: String, args: Manifest[_]*): Manifest[T] = null

  /** Manifest for the intersection type `parents_0 with ... with parents_n'
   */
  def intersectionType[T](parents: Manifest[_]*): Manifest[T] = null
}





/** A Manifest[T] is a descriptor for the type T. 
 */
abstract class Manifest[T] {
  val name:String
  val reflectedClass:Predef.Class[_]
  val caseProductView: T=>Option[Product]
}

abstract case class classManifest[T]() extends Manifest[T]{
}

